#include <iostream>
#include <signal.h>
#include <pthread.h>
#include <thread>
#include <unistd.h>
#include <string.h>
#include <gflags/gflags.h>
#include "DevMngSvr.h"
#include "BackSvr.h"
#include "MsgRequester.h"
#include "define.h"
#include "LoopContrller.h"
#include "proto_package.h"
qjbase::CR5Log g_log;
using namespace google;
using namespace std;

DEFINE_string(ip, "192.168.26.251", "设备请求转发服务ip");
//DEFINE_string(ip, "192.168.26.220", "设备请求转发服务ip");
DEFINE_uint32(port, 9001, "设备请求转发服务端口");
DEFINE_uint32(acksvr, 1, "0-客户端请求 1-服务端响应");
DEFINE_uint64(destadrr, 1, "0-客户端请求 1-服务端响应");
DEFINE_uint64(cnt, 10, "开始服务端个数");
DEFINE_uint64(webcnt, 10, "开始服务端个数");
DEFINE_uint64(tstype, 1, "测试类型 0-文件校验请求 1-分发测试");
DEFINE_uint64(cmd, 1, "0-停止视频上传请求 1-文件校验");
std::vector<CDevMngSvrPtr> vecDveMngSvrPtr;
std::vector<CBackSvrPtr> vecBackSvrPtr;
std::vector<CMsgRequsterPtr> vecWebDevMsgRequst;
static void sig_deal(int signo)
{
	switch (signo)
	{
	case SIGUSR1:
	{
		LOG_INFO("catch SIGUSR1");
		LOG_FLUSH();
	}
	break;
	case SIGUSR2:
		LOG_INFO("catch SIGUSR2");
		LOG_FLUSH();
		break;
	case SIGPIPE:
		LOG_INFO("catch SIGPIPE");
		LOG_FLUSH();
		break;
	case SIGINT:
		LOG_INFO("catch SIGINT, Process Exit");
		LOG_FLUSH();		
		for (auto itr : vecBackSvrPtr)
		{
			itr->StopSvr();
		}							
		for (auto itr : vecDveMngSvrPtr)
		{
			itr->StopSvr();
		}

		for (auto itr : vecWebDevMsgRequst)
		{
			itr->StopSvr();
		}			
		g_LoopContr.StopRun();
		break;
	case SIGTERM:
		LOG_INFO("catch SIGTERM, Process Exit");
		LOG_FLUSH();		
		g_LoopContr.StopRun();
		exit(0);
		break;
	case SIGSEGV:
		break;
	default:
		LOG_INFO("catch SIG %d, Process Maybe core", signo);
		LOG_FLUSH();
		signal(signo, SIG_DFL);
		break;
	}
}
int main(int argc, char **argv) {
	g_log.SetFileKeyWord("LiveServerDispatch");
	g_log.SetPrintStdOut(true);
	if (signal(SIGUSR1, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGUSR1");
	if (signal(SIGUSR2, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGUSR2");
	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
		LOG_ERROR("can't catch SIGPIPE");
	if (signal(SIGTERM, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGTERM");
	if (signal(SIGINT, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGINT");
	if (signal(SIGABRT, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGABRT");
	if (signal(SIGBUS, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGBUS");
	if (signal(SIGSEGV, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGSEGV");
	if (signal(SIGPIPE, sig_deal) == SIG_ERR)
		LOG_ERROR("can't catch SIGPIPE");	
	google::ParseCommandLineFlags(&argc, &argv, true);	
	vector<uint64_t> vecMoudleid;
	for (uint64_t i = 0; i<FLAGS_cnt; i++)
	{
		vecMoudleid.push_back(i);
	}		 	
	if (1==FLAGS_tstype)
	{
		if (FLAGS_acksvr)
		{
			for (size_t i = 0; i < FLAGS_cnt; i++)
			{
				if (i < FLAGS_cnt / 2)
				{
					CDevMngSvrPtr devMngSvrPtr(new CDevMngSvr(g_Loop));
					devMngSvrPtr->SetModuleID(vecMoudleid[i]);
					devMngSvrPtr->StartRegister(FLAGS_ip.c_str(), FLAGS_port);
					vecDveMngSvrPtr.push_back(devMngSvrPtr);
				}

				else
				{
					CBackSvrPtr backsvrPtr(new CBackSvr(g_Loop));
					backsvrPtr->SetModuleID(vecMoudleid[i]);
					backsvrPtr->StartRegister(FLAGS_ip.c_str(), FLAGS_port);
					vecBackSvrPtr.push_back(backsvrPtr);
				}

				usleep(1000);
			}
		}
		else
		{
			for (size_t i = FLAGS_cnt, j = 0; i < FLAGS_cnt + FLAGS_webcnt; i++, j++)
			{
				if (j >= FLAGS_cnt){ j = 0; }
				CMsgRequsterPtr webDevMsgReqPtr(new CMsgRequester(g_Loop));
				webDevMsgReqPtr->SetModuleID(i);
				webDevMsgReqPtr->SetDestMoudleID(j);
				webDevMsgReqPtr->StartSendDevMsg(FLAGS_ip, FLAGS_port);
				vecWebDevMsgRequst.push_back(webDevMsgReqPtr);
				//usleep(20000);
			}
		}	
	}
	else if (0 == FLAGS_tstype)
	{
		//for (size_t i=0; i< 2;i++)
		{
			//if (fork() == 0)
			{
				CMsgRequsterPtr webDevMsgReqPtr(new CMsgRequester(g_Loop));
				webDevMsgReqPtr->SetModuleID(0x100);
				uint32_t moduleid = 0x02050000;
				webDevMsgReqPtr->SetDestMoudleID(moduleid);
				webDevMsgReqPtr->StartSendFileCheckMsg(FLAGS_ip, FLAGS_port);
				webDevMsgReqPtr->StartSendDevMsg(FLAGS_ip, FLAGS_port);
				vecWebDevMsgRequst.push_back(webDevMsgReqPtr);
			//	break;
			}
		}		
	}

	g_LoopContr.StartRun();	
	return 0;
}



